package com.xiguaji.tiktok.v1.web.tiktok.service;

import com.xiguaji.boot.toolkit.JsonUtil;
import com.xiguaji.tiktok.utils.ESUtil;

import com.xiguaji.tiktok.utils.jdbc.PageResponse;
import com.xiguaji.tiktok.v1.tiktok.aweme.dto.BloggerAwemeResponse;
import com.xiguaji.tiktok.v1.tiktok.music.service.MusicService;
import com.xiguaji.tiktok.v1.web.tiktok.dto.SoundBaseResponse;
import com.xiguaji.tiktok.v1.web.tiktok.dto.SoundResponse;
import com.xiguaji.tiktok.v1.web.utils.FormatUtil;
import lombok.extern.slf4j.Slf4j;

import lombok.val;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;


/**
 * 官网热门音乐服务
 *
 */
@Slf4j
@Service
public class TopTiktokSoundService {
    /**
     * client
     */
    @Autowired
    RestHighLevelClient client;

    @Autowired
    MusicService musicService;

    /**
     * 查询开始索引
     */
    private int FROM_INDEX = 0;

    /**
     * 查询页数据大小
     */
    private int PAGE_SIZE = 10;

    /**
     * 在es音乐数据索引中根据userGrowth（用户增长数）查询前10条音乐的相关数据
     * @return List<SoundResponse>
     */
    public List<SoundResponse> getTopTiktokSoundListByEs(Integer fromIndex,Integer pageSize) {
        //返回结果
        List<SoundResponse> musics = new ArrayList<>();

        //设置es查询索引
        SearchRequest searchRequest = new SearchRequest(ESUtil.MUSIC_INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //设置userGrowth排序
        searchSourceBuilder.sort("userGrowth", SortOrder.DESC);

        //设置数量
        searchSourceBuilder.from(fromIndex != null ? fromIndex : FROM_INDEX);
        searchSourceBuilder.size(pageSize != null ? pageSize : PAGE_SIZE);

        searchRequest.source(searchSourceBuilder);

        try {
            //调用es接口查询
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            //接口返回结果
            val hits = searchResponse.getHits().getHits();

            //结果对象实例
            for (SearchHit hit : hits) {
                SoundResponse music = JsonUtil.jsonParse(SoundResponse.class,hit.getSourceAsString());
                // 图片替换
                if(music.getCoverMedium() != null
                        && ((music.getCoverMedium().indexOf("sign-sg") > 0
                        && music.getCoverMedium().indexOf("sign-sg") < 30)
                        || (music.getCoverMedium().indexOf("sign-va") > 0
                        && music.getCoverMedium().indexOf("sign-va") < 30))){
                    music.setCoverMedium(music.getCoverMedium().replace("sign-sg", "amd-va").replace("sign-va", "amd-va").replace("webp", "jpeg"));
                }
                //转换时间
                if(music.getDuration() != null){
                    music.setDurationString(FormatUtil.getTimeStringByInt(music.getDuration()));
                }
                musics.add(music);
            }
        } catch (IOException e) {
            log.error("官网热门音乐服务-音乐列表方法连接es客户端失败：",e);
        }

        return musics;
    }

    /**
     * 在es中根据music获取详情
     * @param mid
     * @return
     * @throws IOException
     */
    public SoundBaseResponse getMusicDetailByEs(long mid){
        //设置es查询
        SearchRequest searchRequest = new SearchRequest(ESUtil.MUSIC_INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("mid",mid));
        searchRequest.source(searchSourceBuilder);
        try {
            //调用es接口
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            if(searchResponse != null && searchResponse.getHits() != null
                    && searchResponse.getHits().getHits() != null
                    && searchResponse.getHits().getHits().length == 0){
                return null;
            }
            //结果
            SoundBaseResponse music = JsonUtil.jsonParse(SoundBaseResponse.class,
                    searchResponse.getHits().getHits()[0].getSourceAsString());
            // 图片替换
            if(music.getCoverMedium() != null
                    && ((music.getCoverMedium().indexOf("sign-sg") > 0
                    && music.getCoverMedium().indexOf("sign-sg") < 30)
                    || (music.getCoverMedium().indexOf("sign-va") > 0
                    && music.getCoverMedium().indexOf("sign-va") < 30))){
                music.setCoverMedium(music.getCoverMedium().replace("sign-sg", "amd-va").replace("sign-va", "amd-va").replace("webp", "jpeg"));

            }
            //设置音乐时间格式
            if(music != null && music.getDuration() != null){
                music.setDurationString(FormatUtil.getTimeStringByInt(music.getDuration()));
            }
            return music;
        } catch (IOException e) {
            log.error("官网热门音乐服务-音乐详情方法连接es客户端失败：",e);
        }
        return null;
    }

    /**
     * 根据music id 获取10条相关视频信息
     * @param mid
     * @return
     */
    public List<BloggerAwemeResponse> getAwemeByMusic(long mid){
        List<BloggerAwemeResponse> videos = new ArrayList<>();
        //获取前10条按观看人数排序的相关视频分页数据
        PageResponse<BloggerAwemeResponse> bloggerAweme = musicService.getAwemePageByMusic(mid,3,1,10,null);
        if(bloggerAweme != null){
            return bloggerAweme.getList();
        }
        return videos;
    }

    /**
     * 随机获取10条音乐信息
     * 调用getTopTiktokSoundListByEs随机获取某一页数据
     * @param mid
     * @param pageSize
     * @return List<SoundResponse>
     */
    public List<SoundBaseResponse> getRecommendedMusic(long mid,Integer pageSize) {
        //调用查询列表方法返回数据，这里多查1条，保证推荐的音乐与本音乐不一样
        List<SoundResponse> soundResponse = getTopTiktokSoundListByEs((int)(Math.random() * 100),pageSize + 1);
        //结果集
        List<SoundBaseResponse> musics = new ArrayList<>();
        //遍历转换SoundBaseResponse，同时如果结果集中有本音乐则去除
        for(int i = 0; i < soundResponse.size() && musics.size() < pageSize; ++i){
            if((soundResponse.get(i) != null && !Objects.equals(mid,soundResponse.get(i).getMid()))){
                musics.add(JsonUtil.jsonParse(SoundBaseResponse.class,
                        JsonUtil.parseJson(soundResponse.get(i))));
            }
        }
        //随机调整位置
        changeRecommendedMusicPos(musics);
        return musics;
    }

    /**
     * 随机调整推荐音乐顺序
     * @param musics
     */
    private void changeRecommendedMusicPos(List<SoundBaseResponse> musics){
        if(musics != null && musics.size() > 1){
            //随机次数，5以内至少1次
            int changeTime = (int)(Math.random() * 5) + 1;
            int musicsLen = musics.size();
            //原位置
            int sourcePos = (int)(Math.random() * musicsLen - 1);
            //替换的位置
            int targetPos = 0;
            //保存临时数据
            SoundBaseResponse temp = musics.get(targetPos);
            while(changeTime > 0){
                if(sourcePos != targetPos){
                    musics.set(targetPos,musics.get(sourcePos));
                    targetPos = sourcePos;
                }
                sourcePos = (int)(Math.random() * musicsLen - 1);
                changeTime--;
            }
            musics.set(targetPos,temp);
        }
    }
}
